# -*- coding: utf-8 -*-
"""
基于 ECharts 的柱状图组件
"""
from .echarts_base import TgEchartsBase
from pyecharts.charts import Bar
from pyecharts import options as opts
import pandas as pd
from datetime import datetime
import numpy as np

class TgBarChartEcharts(TgEchartsBase):
    """基于 ECharts 的柱状图组件"""

    def __init__(self, title="柱状图", parent=None):
        super().__init__(parent)
        self.chart_title = title
        self.series_data = []  # 存储多个系列的数据

    def set_data(self, df: pd.DataFrame, x_column: str, y_column: str, name: str = "数据", colors=None):
        """
        设置柱状图数据
        :param df: 数据DataFrame
        :param x_column: X轴数据列名或直接传入数据
        :param y_column: Y轴数据列名或直接传入数据
        :param name: 系列名称
        :param colors: 柱子颜色列表，可以为每个柱子指定不同颜色
        """
        self.df = df
        
        # 处理x轴数据
        if isinstance(x_column, str) and x_column in df.columns:
            x_data = df[x_column].tolist()
        else:
            x_data = x_column if hasattr(x_column, '__iter__') else df.index.tolist()
        
        # 处理y轴数据
        if isinstance(y_column, str) and y_column in df.columns:
            y_data = df[y_column].tolist()
        else:
            y_data = y_column if hasattr(y_column, '__iter__') else []
        
        # 转换时间数据为字符串格式：如果为零点则仅显示日期
        x_data_str = []
        for x in x_data:
            if isinstance(x, pd.Timestamp):
                dt = x.to_pydatetime()
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    x_data_str.append(dt.strftime("%Y-%m-%d"))
                else:
                    x_data_str.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            elif isinstance(x, datetime):
                dt = x
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    x_data_str.append(dt.strftime("%Y-%m-%d"))
                else:
                    x_data_str.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            elif hasattr(x, 'timestamp'):
                dt = datetime.fromtimestamp(x.timestamp())
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    x_data_str.append(dt.strftime("%Y-%m-%d"))
                else:
                    x_data_str.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            else:
                x_data_str.append(str(x))
        
        # 清空之前的数据并添加新系列
        self.series_data = []
        self.add_series(x_data_str, y_data, name, colors)
        self.update_chart()

    def add_series(self, x_data, y_data, name: str = "数据", colors=None):
        """添加一个数据系列"""
        self.series_data.append({
            'x_data': x_data,
            'y_data': y_data,
            'name': name,
            'colors': colors
        })

    def clear(self):
        """清空图表数据"""
        self.series_data = []
        self.df = None
        if hasattr(self, 'webview') and self.webview is not None:
            self.webview.setHtml("<html><head><meta charset='utf-8'><style>html,body{margin:0;padding:0;overflow:hidden;background:transparent;}</style></head><body></body></html>")

    def create_chart(self) -> Bar:
        """创建柱状图"""
        # 根据当前控件高度设置图表初始化尺寸，宽度自适应
        current_h = self.height() if hasattr(self, 'height') else 0
        height_px = max(160, int(current_h)) if current_h else 220
        init_opts = opts.InitOpts(width="100%", height=f"{height_px}px")
        if not self.series_data:
            chart = Bar(init_opts=init_opts)
            chart.set_global_opts(title_opts=opts.TitleOpts(title=self.chart_title))
            return chart

        chart = Bar(init_opts=init_opts)
        
        # 使用第一个系列的x轴数据
        x_axis_data = self.series_data[0]['x_data'] if self.series_data else []
        chart.add_xaxis(xaxis_data=x_axis_data)
        
        # 添加所有系列
        for series in self.series_data:
            # 处理颜色
            if series['colors']:
                # 如果提供了颜色数组，为每个柱子设置不同颜色
                item_styles = []
                for i, color in enumerate(series['colors']):
                    if i < len(series['y_data']):
                        item_styles.append(opts.ItemStyleOpts(color=color))
                    else:
                        item_styles.append(opts.ItemStyleOpts(color="#5470c6"))  # 默认颜色
                
                # 使用数据项形式来设置每个柱子的颜色
                data_with_style = []
                for i, value in enumerate(series['y_data']):
                    if i < len(series['colors']):
                        data_with_style.append(
                            opts.BarItem(
                                name=str(series['x_data'][i]) if i < len(series['x_data']) else "",
                                value=value,
                                itemstyle_opts=opts.ItemStyleOpts(color=series['colors'][i])
                            )
                        )
                    else:
                        data_with_style.append(value)
                
                chart.add_yaxis(
                    series_name=series['name'],
                    y_axis=data_with_style,
                    label_opts=opts.LabelOpts(is_show=False)
                )
            else:
                chart.add_yaxis(
                    series_name=series['name'],
                    y_axis=series['y_data'],
                    itemstyle_opts=opts.ItemStyleOpts(color="#5470c6"),
                    label_opts=opts.LabelOpts(is_show=False)
                )
        
        # 设置全局选项
        chart.set_global_opts(
            title_opts=opts.TitleOpts(title=self.chart_title),
            tooltip_opts=opts.TooltipOpts(
                trigger="axis",
                axis_pointer_type="shadow"
            ),
            legend_opts=opts.LegendOpts(pos_left="center", pos_top="2%"),
            xaxis_opts=opts.AxisOpts(
                type_="category",
                axislabel_opts=opts.LabelOpts(rotate=45),
            ),
            yaxis_opts=opts.AxisOpts(
                type_="value",
                axislabel_opts=opts.LabelOpts(formatter="{value}")
            ),
            # 使用 inside 数据缩放以节省垂直空间
            datazoom_opts=[opts.DataZoomOpts(type_="inside", xaxis_index=0, range_start=0, range_end=100)],
            toolbox_opts=opts.ToolboxOpts(
                feature={
                    "saveAsImage": {},
                    "restore": {},
                    "dataView": {"readOnly": False},
                    "dataZoom": {},
                    "magicType": {"type": ["line", "bar"]}
                }
            ),
        )

        # 收紧网格边距，减少右侧留白（在 pyecharts 2.x 中不在 set_global_opts 里传入）
        chart.options.update(
            grid=opts.GridOpts(
                pos_left="6%",
                pos_right="2%",
                pos_top="15%",
                pos_bottom="12%",
                is_contain_label=True,
            ).opts
        )
        
        return chart

    def update_chart(self):
        """更新图表"""
        chart = self.create_chart()
        self.render_chart(chart)

    def set_time_range(self, start_time, end_time, enforce_limits=True):
        """设置时间范围（为了兼容性保留此方法）"""
        # ECharts 通过 DataZoom 控制范围，这里可以实现具体的时间范围控制
        pass
